home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / gcoope10.zip / USER10.TXT < prev   
Text File  |  1994-07-21  |  57KB  |  1,329 lines

  1.                              
  2.                              
  3.                              
  4.                              
  5.                              
  6.                              
  7.                              
  8.                              
  9.                              
  10.                              
  11.                              
  12.                              
  13.                              
  14.                              
  15.                              
  16.                              
  17.                              
  18.                              GCOOPE Version 1.0
  19.  
  20.     Generic C-language Object Oriented Programming Environment Version 1.0
  21.  
  22.                               by Brian L. Price
  23.  
  24.                      Released as Public Domain July, 1994.
  25.  
  26.  
  27.  
  28.                                    Table of Contents
  29.  
  30.  
  31.             I. Introduction to Objects....................................1
  32.                A. Object-ively Defined....................................1
  33.                B. Genericity isn't just for canned goods..................2
  34.                C. C. Inheritance without genetics.........................3
  35.                D. Introducing GCOOPE......................................3
  36.  
  37.            II. The GCOOPE Environment.....................................5
  38.                A. Object handles..........................................5
  39.                B. Class variables.........................................6
  40.                C. Instance Variables......................................7
  41.                D. Methods.................................................7
  42.                E. Function Dispatching....................................9
  43.                   1. 1. g is the Name.....................................9
  44.                   2. The Smalltalk Connection............................11
  45.                   3. Local method caching................................11
  46.                   4. Steering the instance...............................13
  47.                F. Classes and Pseudo Classes.............................14
  48.                G. Flag Classes...........................................15
  49.  
  50.            III. Creating a class definition..............................16
  51.                 A. Layout of a class definition module...................16
  52.                 B. Method definition section.............................16
  53.                 C. Installation routine..................................17
  54.  
  55.            IV. Expansion and Growth......................................18
  56.  
  57.  
  58.            Appendices
  59.  
  60.             A. Appendix A. The GCOOPE USER'S GROUP.......................19
  61.             B. Appendix B. About the Author in case you're really bored..20
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.                                            i
  88.  
  89.  
  90.  
  91.                             GCOOPE Version 1.0 User's Guide
  92.  
  93.                              By Brian L. Price July, 1994
  94.  
  95.            I. Introduction to Objects
  96.  
  97.                 A. Object-ively Defined
  98.  
  99.                           Before diving into GCOOPE, let us take a few
  100.                      moments to examine the concept object.  My pocket
  101.                      dictionary provides a starting point with two
  102.                      interesting definitions:
  103.  
  104.                           1.  Object - Something serving as a focus of
  105.                                attention or ACTION.
  106.  
  107.                           2.  Object - (Grammer) A noun that receives or is
  108.                                affected by the action of a verb....
  109.  
  110.                           An object is first of all a thing, something that
  111.                      exists in a perceptible form, in other words data.
  112.                      That data is the focus of actions, it is changed,
  113.                      translated, or simply accessed by a verb (method).
  114.  
  115.                           If we consider the verb to be a method for
  116.                      performing an action, and that method is described as a
  117.                      computer algorithm, we have the 'active' portion of the
  118.                      definition.
  119.  
  120.                           Another way of saying object is active data.  Now
  121.                      how do we apply this concept to computer programming?
  122.                      We must first lay out some useful principles.  Lets
  123.                      borrow some tried and true programming principles as a
  124.                      start:
  125.  
  126.                           1.  Modularity - modular code is self contained
  127.                                (at least as much as possible), and it has a
  128.                                well defined interface to the outside world.
  129.                                Since our object concept is already a
  130.                                seperate entity from its surroundings,
  131.                                enforcing the principle of modularity helps
  132.                                to keep it that way.
  133.  
  134.                           2.  Orthagonality - The set of methods that we
  135.                                define to act upon our object's data should
  136.                                be orthagonal.  In other words if you define
  137.                                an add operation, you must define a subtract
  138.                                operation.  This goes hand in hand with our
  139.                                first principle.  If our set of methods is
  140.                                complete and orthagonal, then there is no
  141.                                need for outside intervention.
  142.  
  143.                           So our concept of object now consists of a piece
  144.                      of data that can be acted upon by an orthagonal set of
  145.                      methods with a well defined interface, and all this is
  146.                      contained as a seperate entity from its surroundings.
  147.                      Lets call this encapsulation.
  148.  
  149.                                            1
  150.  
  151.  
  152.  
  153.                           Now, by itself, our encapsulated object concept
  154.                      isn't more powerful than procedurally written code.
  155.                      (Although it would be easier to debug.)  We need a few
  156.                      more concepts to build upon what we already have.
  157.  
  158.  
  159.                 B. Genericity isn't just for canned goods.
  160.  
  161.                           If you have ever been short on cash, or frugal,
  162.                      you have probably purchased a generic product.
  163.                      Something that is generic is the same as any other
  164.                      thing of the same type or class, at least in all the
  165.                      functional ways.  A generic item can be substituted for
  166.                      any other item of the same type.
  167.  
  168.                           What if we develop a set of encapsulated objects,
  169.                      a subset of whose methods are remarkably similar in
  170.                      function, lets say that those methods are math
  171.                      functions.  Now if one of those objects has integer
  172.                      data and another has floating point data,  an add
  173.                      operation performs the same type of action on both
  174.                      objects.  Thus we could say that in this case add is a
  175.                      generic action.
  176.  
  177.                           If we provide a suitable method for detecting
  178.                      which object should be called depending upon the data
  179.                      type, we can develop a generic function add.  It won't
  180.                      matter if its operand is of type float or integer
  181.                      because the correct object method will perform the
  182.                      actual operation.  Thus we have the concept of a
  183.                      generic function label.
  184.  
  185.                           This concept makes our object concept a bit more
  186.                      powerful.  Now, wherever we have similar operations
  187.                      performed on different types of data, we can define one
  188.                      label which we can then use for that operation no
  189.                      matter what the actual data type is.  We have
  190.                      simplified our interface, since there are fewer
  191.                      function labels required.
  192.  
  193.                           More importantly, we no longer have to know the
  194.                      exact type or structure of the piece of data we are
  195.                      manipulating, all we have to know is that the operation
  196.                      we want to perform is a valid one for that object.  To
  197.                      simplify if the desired action is filling a basket with
  198.                      fruit, do we really care if it gets filled with peaches
  199.                      in place of tangerines?  Genericity gives us a degree
  200.                      of data independence.
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.                                            2
  212.  
  213.  
  214.                 C. C. Inheritance without genetics
  215.  
  216.                           We now have encapsulated objects with generic
  217.                      methods, what could make this concept more powerful ?
  218.                      In traditional programming we push complexity down the
  219.                      procedure chain.  The real work gets done in seperate
  220.                      functions that we define to do a job.  This allows us
  221.                      to concentrate on the big picture without being
  222.                      overwhelmed by details.  The layout of a program looks
  223.                      like an upside down tree structurally.
  224.  
  225.                           What if we have written an object to do a simple
  226.                      task and now we want to do a more difficult task that
  227.                      has the simple task as a necessary sub-task.
  228.                      Traditionally, we would call a subroutine.  We could do
  229.                      that with our objects, but is there a better way ?
  230.  
  231.                           Consider the upside down structure tree of the
  232.                      traditional program to be a family tree and the answer
  233.                      is obvious.  What if we could define a new object that
  234.                      would automatically gain all the capabilities and data
  235.                      structures of the old object ?  This is the concept
  236.                      called inheritance.  If we define a child object with
  237.                      the old object as its parent, we can gain all its
  238.                      abilities (methods) through inheritance.
  239.  
  240.                           Can we do better ?  Sure, we can allow multiple
  241.                      ancestory ie. more than one parent, we can allow
  242.                      partial ancestory ie. gaining only a subset of the
  243.                      parent's capabilities, and we can redefine the parent
  244.                      capabilities adding our own structure and actions on
  245.                      top of what we inherit.
  246.  
  247.                           Inheritance lets us both change and build upon the
  248.                      characteristics of the parent.  This concept is made
  249.                      even more powerful by our earlier insistance on
  250.                      encapsulation.  The parent can be changed to adapt it
  251.                      to new requirements and as long as the original
  252.                      interface and capabilities are not changed or removed,
  253.                      it makes no difference to the child object.
  254.  
  255.  
  256.                 D. Introducing GCOOPE
  257.  
  258.                           We have reached the point where we have developed
  259.                      a quite powerful and useful concept.  Now how do we
  260.                      apply it ?
  261.  
  262.                           Brute force is always a good first shot,  so we
  263.                      could write a program module that would define a data
  264.                      type or structure and methods (ie functions) to perform
  265.                      actions upon it.  Well, we'll probably need more than
  266.                      one so we'll have to create and track each....
  267.                      INSTANCE!  Hmm, we have a set of these data regions or
  268.                      instances, and we need only one set of methods to act
  269.                      upon them since they are all members of the same,...
  270.                      CLASS!
  271.  
  272.  
  273.                                            3
  274.  
  275.  
  276.                           Okay so we have this set of methods and data
  277.                      structure definitions for a class of object, lets call
  278.                      this the class definition.  We need some sort of
  279.                      instance tracking database, lets use a variable to
  280.                      represent each instance.  Call it type object, so I
  281.                      guess the variables would be OBJECT HANDLES.
  282.  
  283.                           There's the first step, now lets incorporate the
  284.                      concept of genericity.  We need some way of tracking
  285.                      all these methods for each of the .... GENERIC (shape
  286.                      changing) functions.   Heck, we need some way of
  287.                      tracking all these generic function labels.  Routing
  288.                      all these generic calls is going to be as bad as
  289.                      running a taxi service in Manhattan, we need a ....
  290.                      DISPATCHER to tell them where to go.
  291.  
  292.                           Now for inheritance, we'll just add our ancestor's
  293.                      methods and instance memory to our own, of course we
  294.                      need a way to add our own methods that will overwrite
  295.                      any inherited methods for the same generic, and we have
  296.                      to keep track of which instance of the parent class
  297.                      belongs to our own instance,... you know we need a
  298.                      couple of object classes just to do all these things.
  299.  
  300.                           At this point GCOOPE politely knocks at your door
  301.                      offering its services.  GCOOPE has lists to track
  302.                      object classes and instances, it has a powerful
  303.                      function dispatcher and instance tracking mechanism, in
  304.                      addition it addresses problems we haven't even
  305.                      considered yet in this discussion.  Topics like default
  306.                      destructors, temporary object deletion, error handling,
  307.                      class definition objects, and more.  Best of all GCOOPE
  308.                      is written in and for the C programming language, bare
  309.                      metal power cloaked in an object friendly environment.
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.                                            4
  336.  
  337.  
  338.            II. The GCOOPE Environment
  339.  
  340.                      In this section, we will explore the strengths and
  341.                 weaknesses of the GCOOPE system and its implementation.
  342.                 GCOOPE is a powerful system but there are pitfalls and costs
  343.                 in using it.  GCOOPE, like most other real world systems, is
  344.                 a product of choices between often conflicting goals and the
  345.                 resulting system is defined by those design choices.
  346.  
  347.  
  348.                 A. Object handles
  349.  
  350.                           The data type object, defined in both pcstruct.h
  351.                      and GCOOPE31.h, is primarily used as a 'handle' for an
  352.                      object class or instance.  The type object is defined
  353.                      in such a way that it is always at least 32 bits in
  354.                      size.  It is normally defined as a long integer.
  355.  
  356.                           For practical purposes, you can consider the
  357.                      object handle to be the object although in actuality it
  358.                      serves as a special type of index/pointer with internal
  359.                      structure members.  For the actual details of the
  360.                      object handle structure, consult the T.R.M. (Technical
  361.                      Reference Manual).
  362.  
  363.                           A secondary use of the data type object is to
  364.                      return values from a method function.  When used in
  365.                      this manner, it should be cast as the appropriate data
  366.                      type if it is being used to return something other than
  367.                      an object handle.  See the basic class libraries and
  368.                      the gcoope10.h file for assistance macros.
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.                                            5
  398.  
  399.  
  400.                 B. Class variables
  401.  
  402.                           Class variables are variables or data structures
  403.                      that are accessible to all instances of that class.
  404.                      They are static variables that are the same for all
  405.                      instances of the class.
  406.  
  407.                           The structure for a class variable area is defined
  408.                      in the class definition, each class can have at most
  409.                      one class variable structure/area.  Another way of
  410.                      stating this is to say that the class variable
  411.                      structure area is a shared memory area private to class
  412.                      members but shared among those same members.  All class
  413.                      variables must be accessed as members of the class
  414.                      variable structure.
  415.  
  416.                      WARNING: In GCOOPE it is possible to access the class
  417.                           variable area of another class.  DON'T.  This type
  418.                           of practice defeats the purpose of encapsulation.
  419.                           If a change occurs to the structure in the owning
  420.                           class, you are in the same situation that you
  421.                           would be in with C++ friends, or normal C code,
  422.                           namely code re-write and re-compile time!
  423.  
  424.                           In order to access the class variable area use the
  425.                      public kernel function, getCVptr.  Full details of this
  426.                      function is given in the T.R.M.  The class variable
  427.                      area is automatically created when the class definition
  428.                      is installed.
  429.  
  430.                           When a class definition is installing itself as an
  431.                      instance of class 'Class', the size of the class
  432.                      variable structure must be passed as the cvSize
  433.                      parameter.
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.                                            6
  460.  
  461.  
  462.                 C. Instance Variables
  463.  
  464.                           Instance variables are variables or data
  465.                      structures that belong to an instance of a class.  This
  466.                      is a private static memory area for the instance.  Each
  467.                      instance of a class will have a separate instance
  468.                      variable memory area.
  469.  
  470.                           The structure for an instance variable area is
  471.                      defined in the class definition.  Each class may have
  472.                      at most one instance variable structure.  All instance
  473.                      variables must be referenced as members of that
  474.                      structure.
  475.  
  476.                      WARNING:  In GCOOPE, it is possible to access the
  477.                           instance memory for another class, or ancestor
  478.                           instance.  DON'T.  This practice makes your code
  479.                           dependant on the internal structure of those other
  480.                           modules, it defeats the entire purpose of
  481.                           encapsulation.  Using this type of practice will
  482.                           result in code that is full of side effects and
  483.                           cross dependancies.
  484.  
  485.                           To create the instance variable memory area, you
  486.                      must use the public kernel function makeInst.  Full
  487.                      details of this function is given in the T.R.M.  This
  488.                      function should only be called within the constructor
  489.                      (New) method of a class.  It must be called prior to
  490.                      any ancestor constructor calls.
  491.  
  492.                           To access the instance variable memory area, you
  493.                      use the public kernel function getIVptr.  Full details
  494.                      on the use of this function is given in the T.R.M.
  495.  
  496.                           When a class definition is installing itself as an
  497.                      instance of the class 'Class', the size of the instance
  498.                      variable structure must be passed as the parameter
  499.                      ivSize.
  500.  
  501.  
  502.                 D. Methods
  503.  
  504.                           The generic GCOOPE method prototype is defined as:
  505.  
  506.                                typedef object (*method)(object,...);
  507.  
  508.                           A function of type method takes at least one
  509.                      parameter of type object and returns a type object.
  510.                      The first passed parameter must always be an object
  511.                      handle of type object.  Additional parameters may be
  512.                      passed.
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.                                            7
  522.  
  523.  
  524.                           In our method type definition, you may observe the
  525.                      use of the variable argument parameter ...  This is
  526.                      handy because we can use that one type method no matter
  527.                      how many parameters are actually required by an actual
  528.                      method.  This does present some dangers.
  529.  
  530.                           First, passing a pointer as a variable argument
  531.                      parameter is like running barefoot through a minefield.
  532.                      Second, passing different data types in a variable
  533.                      argument list is like adding machine gun and mortar
  534.                      fire to that minefield.  Unless your name is Superman,
  535.                      you will take serious hits.
  536.  
  537.                           At first glance, it seems we've put ourselves in a
  538.                      dilemma, we have a powerful abstraction that is too
  539.                      dangerous to use, right?  Wrong.  Why are you passing
  540.                      pointers to a method in the first place ???  You should
  541.                      be passing object handles!  Object handles are much
  542.                      safer because they undergo some error checking and
  543.                      their internal structural integrity is verifiable.  In
  544.                      fact, you can add even more error-checking on top of
  545.                      the built-in checks in your class definitions.
  546.  
  547.                           As for multiple data types, we already have a type
  548.                      object which can be used to pass almost any other data
  549.                      type.  Why not use it?  If you only pass one parameter
  550.                      in the variable argument field and if you are careful
  551.                      in your design of object class definitions, it is
  552.                      convient and fairly safe to pass a pointer or other
  553.                      data type.  However, with multiple parameters, take
  554.                      heed.
  555.  
  556.                      1. RULE #1
  557.                                When writing a method for use by an
  558.                           applications program, if more than one parameter
  559.                           is to be passed in the variable argument portion,
  560.                           always use type object for all variable argument
  561.                           list parameters, and always use an object handle
  562.                           to an object instance rather than any pointers to
  563.                           memory areas.
  564.                                Another solution is to use the experimental
  565.                           strong typing option.  See typing.h.  The best
  566.                           approach is probably to use a combination of the
  567.                           above advice, judicious use of strong typing and
  568.                           when in doubt be sure and use the return value
  569.                           typedefs.
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.                                            8
  584.  
  585.  
  586.                 E. Function Dispatching
  587.  
  588.                           The function dispatching and instance tracking
  589.                      system in GCOOPE version 1.0 is far more sophisticated
  590.                      than in the earlier.  Used correctly, they can make
  591.                      your programming chores easier, used incorrectly you
  592.                      will need a good debugger.
  593.  
  594.                      1. 1. g is the Name
  595.  
  596.                                The function g is GCOOPE's function
  597.                           dispatcher, its usage is deceptively simply.  Even
  598.                           though complete details are given in the Technical
  599.                           Reference Manual for the GCOOPE kernel, I'll
  600.                           repeat the usage info here.
  601.  
  602.                           returnObjectValue = g(generic)(objectInstance,
  603.                                                         [methodParms,...]);
  604.  
  605.                                Where: returnObjectValue is a return value of
  606.                           type object that is returned from the dispatched
  607.                           method; generic is the generic function value of
  608.                           type generic; objectInstance is the object type
  609.                           object handle of the instance or class being acted
  610.                           upon; and the optional methodParms,.... are the
  611.                           parameters passed to the method.
  612.  
  613.                                If you want the details of its operation, see
  614.                           the Technical Reference Manual, here, just take
  615.                           for granted that it works as advertised.
  616.  
  617.                           WARNING: SEE RULE #1
  618.  
  619.                                1.    Incorrect casting of the return value
  620.                                     either in the calling routine or in the
  621.                                     method executed.  32 bit values are
  622.                                     always passed, however depending on the
  623.                                     method, all 32 bits may not be valid.
  624.                                     Be sure to clearly specify in the class
  625.                                     definitions what values are being
  626.                                     returned by their methods.  Also,
  627.                                     whenever possible all methods with the
  628.                                     same generic name should return the same
  629.                                     data type.  Otherwise you will be using
  630.                                     the alternate definition of generic.
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.                                            9
  646.  
  647.  
  648.                                2.    Passing the wrong type in the method
  649.                                     parameter list.  GCOOPE is a weakly
  650.                                     typed system, method parameters are NOT
  651.                                     type checked, so stay alert.  Wherever
  652.                                     possible in your method definitions be
  653.                                     sure and validate the recieved
  654.                                     parameters.
  655.                                          If possible, use the experimental
  656.                                     strong typing option.  It DOES provide
  657.                                     type checking for method parameters,
  658.                                     although it is a bit awkward to use.
  659.  
  660.                                3.    Passing a char or int type as the
  661.                                     objectInstance parameter instead of an
  662.                                     object type.  Can you say "abnormal
  663.                                     program termination" ?
  664.  
  665.                                It cannot be stressed enough, GCOOPE is
  666.                           weakly typed, this is both a blessing and a curse,
  667.                           a strength and a weakness.  If you are the type of
  668.                           programmer that commonly expects the compiler to
  669.                           catch or correct your type casting, I strongly
  670.                           suggest that you use the strong typing option and
  671.                           use the return value typedefs.
  672.  
  673.                                Another point to watch for: with variable
  674.                           argument prototyping such as that used by GCOOPE,
  675.                           it is tempting to define methods for the same
  676.                           generic function that take a different number of
  677.                           parameters or totally different data types as
  678.                           arguments.  DON'T.  That is asking for trouble.
  679.  
  680.                                The only exceptions to this are the  generic
  681.                           functions New and Err, the definition of these
  682.                           functions require that you use different numbers
  683.                           and types of parameters.  Just be careful and
  684.                           don't carry the practice any further than
  685.                           absolutely necessary.
  686.  
  687.  
  688.                           TIP:       While it is handy to use the same
  689.                                generic    function for many similar methods,
  690.                                make sure that the methods truly are similar
  691.                                enough to justify it.  Not only are you
  692.                                tempted to use different parameter types or
  693.                                numbers as noted above, but you will also be
  694.                                slowing down your program when you improperly
  695.                                apply methods to generics.  generic functions
  696.                                with large numbers of methods are slower in
  697.                                dispatching.
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.                                           10
  708.  
  709.  
  710.                      2. The Smalltalk Connection
  711.  
  712.                                If you have previous experience with
  713.                           Smalltalk, GCOOPE will smell like home.  There are
  714.                           a few snakes in the garden however.  Smalltalk
  715.                           makes regular use of trivial methods, methods such
  716.                           as +.  While you may define the equivalent Plus
  717.                           and the like generics in GCOOPE, don't use them
  718.                           where execution speed is important.
  719.  
  720.                                You will have noticed that GCOOPE methods
  721.                           execute an order of magnitude faster than
  722.                           Smalltalk methods.  This is because GCOOPE methods
  723.                           are compiled C code while Smalltalk methods are
  724.                           interpreted code.  What may not be so readily
  725.                           apparent is that GCOOPE's function dispatching is
  726.                           very similar to Smalltalk's and so it is not much
  727.                           faster.   What happens with 'trivial' methods is
  728.                           that the execution time for function dispatching
  729.                           dwarfs the execution time for the method.  In
  730.                           other words, GCOOPE will slow down to near
  731.                           Smalltalk speeds when executing these types of
  732.                           methods.
  733.  
  734.                                When speed is critical, and you only need to
  735.                           call such a method once or twice, do these
  736.                           'trivial' methods locally where possible.  For
  737.                           another idea see the next section.
  738.  
  739.                                All in all, the use of Smalltalk techniques
  740.                           is generally a very good idea, GCOOPE is very
  741.                           close in concept to the idea of compiled
  742.                           Smalltalk.  They share many of the same strengths
  743.                           and mannerisms.  One trap to avoid is forgetting
  744.                           that GCOOPE has more capabilities with regards to
  745.                           inheritance than Smalltalk does, so don't miss out
  746.                           on reaping those benefits.
  747.  
  748.  
  749.                      3. Local method caching
  750.  
  751.                                If you are going to call the same method more
  752.                           than once or twice in the same statement block or
  753.                           routine,  you can drastically decrease the
  754.                           execution time of the dispatching process.  Just
  755.                           use the following call:
  756.  
  757.                                methodToCall=p(generic, instanceObject);
  758.  
  759.                           Where: methodToCall is a method type variable used
  760.                                to hold the method address; generic is the
  761.                                generic function index; and instanceObject is
  762.                                the object type object handle for the
  763.                                instance.
  764.  
  765.  
  766.  
  767.  
  768.  
  769.                                           11
  770.  
  771.  
  772.                                For this technique to apply, instanceObject
  773.                           must remain constant, or must be a non-inherited
  774.                           flag class instance of the same constant class.
  775.                           (flag classes will be explained in detail later,
  776.                           also see the T.R.M.)
  777.  
  778.                                Also if instanceObject is not a non-inherited
  779.                           flag class, you will have to make the following
  780.                           call prior to the one above:
  781.  
  782.                           instanceObject = steer(ClassOfMethod,
  783.                           instanceObject);
  784.  
  785.                                This will set the instanceObject's instance
  786.                           tracking variable to correctly point to the
  787.                           desired instance data.
  788.  
  789.                                With all the above limitations, this
  790.                           technique will not be used often, it can however
  791.                           be used in some cases to get around the 'trivial'
  792.                           method penalty described in the previous section.
  793.  
  794.                                PROGRAMMER'S NOTE:  The best solution to the
  795.                           need for speed in function dispatching is to
  796.                           rewrite the dispatcher so that it does not make
  797.                           any function calls.  Then if writing a platform
  798.                           dependant version, you can drop to assembly and
  799.                           hand-optimize the result of the first step.  This
  800.                           is the path I used in tests of PCOOPE version 2.1
  801.                           and while the dispatcher has changed quite a bit,
  802.                           the new dispatcher should be capable of reaching
  803.                           comparable speeds.  (In 2.1 the speed increase was
  804.                           quite remarkable (try >10x) and well worth the
  805.                           effort.)  If you have a copy of version 2.1
  806.                           examine the dispatcher routine for hints.
  807.  
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.                                           12
  832.  
  833.  
  834.                      4. Steering the instance
  835.  
  836.                                In the section above you caught your first
  837.                           glimpse of the function steer.  It is used to
  838.                           'steer' the instance tracking mechanism so that
  839.                           makeInst and getIVptr will work correctly.
  840.                           Normally this is done automatically by the
  841.                           dispatcher.  However there are certain instances
  842.                           where you must call steer from within your class
  843.                           definitions.
  844.  
  845.                           a. RULE #2
  846.                                     The rule for the need for a manual call
  847.                                to steer is: any time you are calling a
  848.                                generic function that will dispatch to a
  849.                                method that is defined in an ancestor of the
  850.                                current class, you must use manual steer
  851.                                -ing.  Prime examples of this situation occur
  852.                                in methods for the generics New and Kill (and
  853.                                to a lesser extent in Err).  The procedure is
  854.                                fairly simple:
  855.  
  856.                                retVal=g(generic)(steer(ancestor,
  857.                                                         instance),[parms]);
  858.  
  859.                                Where: ancestor is the class object handle
  860.                                     for the ancestor class; and instance is
  861.                                     the object handle for the current
  862.                                     instance.
  863.  
  864.                                This situation occurs because the current
  865.                           instance is used by the dispatcher to determine
  866.                           what the current class is.   If the current class
  867.                           and an ancestor class have methods for the same
  868.                           generic, you could never reach the ancestor method
  869.                           because the dispatcher would call the current
  870.                           class method.  The above call 'fools' the
  871.                           dispatcher into believing that the ancestor class
  872.                           is already the current class and so the call goes
  873.                           through.  Also see the macro ST() in gcoope10.h.
  874.  
  875.                                Some commercial products similar in concept
  876.                           to GCOOPE initialize the ancestor classes for you
  877.                           prior to calling the child class's method for New.
  878.                           The problem with this is, that either you end up
  879.                           with dozens of parameters in the call (to pass all
  880.                           the ancestor initialization parms and don't ask me
  881.                           how you track that with multiple ancestory) or you
  882.                           don't have any control over ancestor
  883.                           initialization. Frankly, either case is
  884.                           unacceptable.
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.                                           13
  894.  
  895.  
  896.                                The above solution isn't what I sought, but
  897.                           it is usable and achieves the desired purpose.
  898.                           The only other solutions I could find added way
  899.                           too much complexity to the kernel code and still
  900.                           didn't solve the occasional problem of calling an
  901.                           ancestor method outside of New or Kill.   You
  902.                           would have a bigger, slower function dispatcher,
  903.                           and still need the steer routine!
  904.  
  905.                                You will also need to use the above technique
  906.                           in your Kill methods wherever they occur, for
  907.                           exactly the same reasons.  Another place where you
  908.                           may find yourself in need of the above solution is
  909.                           when you redefine an ancestor method in a way that
  910.                           adds to the inherited method.  In other words,
  911.                           where you still need to call the ancestor method.
  912.  
  913.                                Another way to look at the above is, if you
  914.                           don't know the ancestor class you don't need to
  915.                           call steer.  Applications programs should never
  916.                           need it.
  917.  
  918.                                Performance wise, the extra call doesn't hurt
  919.                           you very much.  First because the dispatcher won't
  920.                           have to go through a steer procedure, and second
  921.                           because it will only occur normally in the
  922.                           constructor, destructor, or error handler portion
  923.                           of the class definition.  New and Kill methods are
  924.                           one time cost routines per object instance and if
  925.                           your code is calling Err very often something is
  926.                           wrong <GRIN>.
  927.  
  928.  
  929.                 F. Classes and Pseudo Classes
  930.  
  931.                           We have not yet reached the point where we are
  932.                      ready to begin writing class definitions, but in order
  933.                      to understand some of the next section, you need to
  934.                      introduce yourself to some of the concepts.
  935.  
  936.                           Classes are comprised of an optional class
  937.                      variable structure definition, an optional instance
  938.                      variable structure definition, method definitions, and
  939.                      an installation function.
  940.  
  941.                           Pseudo classes are classes that cannot be properly
  942.                      inherited, they have no class or instance variable
  943.                      structure definitions, although they may make use of
  944.                      structure definitions defined internally or externally.
  945.                      Pseudo classes may define methods, although they don't
  946.                      have to.  They may also define non-generic functions.
  947.                      They must include an installation procedure.
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.                                           14
  956.  
  957.  
  958.                           An installation procedure installs the class or
  959.                      pseudo class definition into the GCOOPE system.  It is
  960.                      responsible for inheritance and genericity.  For a
  961.                      class definition, it is also the place where class
  962.                      variables may be initialized.
  963.  
  964.                           Non-generic functions are simply standard C
  965.                      library type functions instead of generic function
  966.                      methods.
  967.  
  968.                           Class definitions are where objects are defined,
  969.                      pseudo class definitions interface to the platform
  970.                      and/or hardware.  Pseudo class definitions are also
  971.                      used to expand GCOOPE's kernel adding necessary or
  972.                      optional functionality.  The pseudo class concept was
  973.                      developed because of a desire to treat kernel expansion
  974.                      in a modular way that could make use of kernel
  975.                      resources used by normal class definition modules.
  976.  
  977.  
  978.                 G. Flag Classes
  979.  
  980.                           The last topic to cover in the GCOOPE environment
  981.                      is the flag class.  A flag class uses a portion of the
  982.                      object handle as an index to its class object.  This
  983.                      means that the lower 16  bits of the object handle are
  984.                      no longer needed by the GCOOPE system.
  985.  
  986.                           A flag class uses those 16 bits as its instance
  987.                      variable storage area.  Thus, for the overhead of a
  988.                      simple flag check, flag classes can implement classes
  989.                      such as Boolean, Char, Int, etc. with no instance
  990.                      memory being dynamically allocated!  For full details
  991.                      of the object handle structure see the T.R.M.
  992.  
  993.                           A flag class is subject to certain limitations.
  994.                      First, it cannot inherit any class which has instance
  995.                      variables.  Second, it must check to see if it is the
  996.                      owner of the instance object handle in each method
  997.                      prior to accessing the instance variable.  Third the
  998.                      New method for such a class must be dual purpose.  If
  999.                      it is being inherited, it must behave exactly as a
  1000.                      normal class.
  1001.  
  1002.                           Basically, the flag class must be careful to check
  1003.                      whether or not it has been inherited with respect to
  1004.                      the current instance.  If it has been, it must behave
  1005.                      exactly like a normal class.  (Note: a flag class's
  1006.                      ivSize must be given as sufficient to store its
  1007.                      variable type.)  Before attempting to create a flag
  1008.                      class definition, it is strongly suggested that you
  1009.                      study the relevant portions of the T.R.M. closely and
  1010.                      also be sure to check the example code provided.
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.                                           15
  1018.  
  1019.  
  1020.            III. Creating a class definition
  1021.  
  1022.                 A. Layout of a class definition module
  1023.  
  1024.                           The first statement in a class definition is
  1025.                      #define CLASS <className>.  This names the class and
  1026.                      becomes the symbol string name for it.  The second
  1027.                      statement is #include "GCOOPE31.h" and the third
  1028.                      statement is object CLASS;.
  1029.  
  1030.                           Following those statements should be your
  1031.                      structure definitions for the class variable and
  1032.                      instance variable structures.  These structures are
  1033.                      optional.  Hint: instead of creating them as a named
  1034.                      structure, typedef them as a structure.
  1035.  
  1036.                           Next should be the class constructor method
  1037.                      definition, followed by any user defined method
  1038.                      definitions and by a destructor and error handling
  1039.                      method if desired.
  1040.  
  1041.                           The final portion of the class definition is the
  1042.                      class installation function definition.
  1043.  
  1044.  
  1045.                 B. Method definition section
  1046.  
  1047.                           The only method you must define is a constructor.
  1048.                      It should call makeInst and then call the constructors
  1049.                      of each superClass by:
  1050.                         p(New)(steer(superClass,instance),[initParms]);
  1051.  
  1052.                           Other than that, you're on your own as far as
  1053.                      methods go.  Just make sure they all fit the following
  1054.                      prototype:  retValType methodName(object,...);.
  1055.  
  1056.                           A few points to remember however, if you
  1057.                      dynamically allocate memory within your object:
  1058.  
  1059.                           1.    use the kernel memory management shells
  1060.                                s_calloc, s_free, s_malloc, and s_realloc.
  1061.  
  1062.                           2.   write a method for Kill that frees the memory
  1063.                                and calls p(Kill)(steer(superClass,
  1064.                                instance)); for each superClass.  (immeadiate
  1065.                                parent) and ending with p(Kill)(Object,
  1066.                                instance);.
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.                                           16
  1080.  
  1081.  
  1082.                 C. Installation routine
  1083.  
  1084.                           The name of the class installation routine MUST be
  1085.                      given as the macro CLASS_INSTALL.  This insures
  1086.                      compatibility with the class installation macros.  The
  1087.                      first statement after any local variable and pointer
  1088.                      declarations is:
  1089.  
  1090.                      CLASS =
  1091.                        p(New)(Class, sizeof(classVarStruct),
  1092.                               sizeof(instanceVarStruct), [SuperClass object
  1093.                               handle list], END);
  1094.  
  1095.                           This creates the class definition, you may now
  1096.                      optionally get a pointer to the class variables area by
  1097.                      getCVptr and initialize the class variables.
  1098.  
  1099.                           The next step is to add each method, this is done
  1100.                      by:
  1101.                        addPMthd(CLASS, genericName, methodAdr);
  1102.  
  1103.                           You can also block ancestor methods for a generic
  1104.                      via rmvPMthd (see T.R.M.).  This is useful for ancestor
  1105.                      methods which should not be directly called except from
  1106.                      a method defined by this class definition.
  1107.  
  1108.                           A note here about inheritance, the call to
  1109.                      p(New)(Class,...) will setup a description of an
  1110.                      instance memory block for instances of this class.
  1111.                      That description includes the instance memory blocks
  1112.                      for all ancestors.  After performing that setup, the
  1113.                      class creation method will add ALL the ancestor methods
  1114.                      to the current class automatically.  The order that you
  1115.                      specify superClasses (immediate ancestors) is
  1116.                      important.  Those given first in the list will take
  1117.                      precedence over later entries.  Their methods will
  1118.                      overwrite any conflicting or overlapping methods for a
  1119.                      generic.  When you use addPM or rmvPM you will
  1120.                      overwrite or remove any listed ancestor method for the
  1121.                      generic in question.
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.                                           17
  1142.  
  1143.  
  1144.            IV. Expansion and Growth
  1145.  
  1146.                      In the short documentation with the PCOOPE version 2.1
  1147.                 release, I foolishly stated that the interface was written
  1148.                 in stone and that all expansion and growth would occur
  1149.                 through the class definitions.  Alas, as so aptly put by the
  1150.                 first user's group member, G/PCOOPE isn't ready for that.
  1151.                 He was 100% correct.
  1152.  
  1153.                      In version 1.0 I have attempted to write the kernel in
  1154.                 an expandable manner.  That is one reason why the provided
  1155.                 code is optimized for little else than debugging.  For each
  1156.                 target platform, an optimized version of the appropriate
  1157.                 kernel module(s) should be created.  Low level functions
  1158.                 that prove necessary can be added via the pseudo class
  1159.                 expansion module route.  In the design of this system, I
  1160.                 have attempted to provide for the possiblity of future
  1161.                 expansion at each level of the system.
  1162.  
  1163.                      GCOOPE has potential as an application framework.  For
  1164.                 that potential to be realized standard, generic, well
  1165.                 defined, and expandable interface specifications need to be
  1166.                 developed.  Available public domain libraries that help to
  1167.                 meet these needs should be incorporated as expansion
  1168.                 modules.  No doubt, some custom code will have to be
  1169.                 written.  The GUI portion alone will prove quite an
  1170.                 undertaking, if GCOOPE is to realize its potential a GUI
  1171.                 specification must provide a path to compatibility with
  1172.                 Windows, X-windows, and other popular GUI environments.
  1173.  
  1174.                      GCOOPE also has potential as an object oriented
  1175.                 operating system extension.  In this concept, the GCOOPE
  1176.                 kernel would be a system resource with instantiated memory.
  1177.                 Such an extension would have to include the ability to share
  1178.                 dynamically loaded modules.  This type of extension to the
  1179.                 GCOOPE framework is not as difficult as it might sound at
  1180.                 first, GCOOPE could be made available as a process on a Mach
  1181.                 3.0 or QNX microkernel.  There would, no doubt, be many
  1182.                 additional demands placed upon the GCOOPE system however.
  1183.  
  1184.                      As of this writing, GCOOPE is in its infancy, at the
  1185.                 very least it serves as an exploratory framework into the
  1186.                 next generation of object oriented programming languages,
  1187.                 application frameworks, and operating systems, at the most
  1188.                 .... you be the judge.  Or better yet, join the GCOOPE
  1189.                 user's group and join in the expansion and implementation of
  1190.                 the GCOOPE system.
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.                                           18
  1204.  
  1205.  
  1206.            Appendix A. Appendix A. The GCOOPE USER'S GROUP
  1207.  
  1208.  
  1209.                           JOIN THE GCOOPE USER'S GROUP!
  1210.  
  1211.  
  1212.                 For a one year membership send check/money order in the
  1213.                 amount of $20.00, (made payable to Brian Lee Price) to the
  1214.                 address below:
  1215.  
  1216.                           Brian Lee Price
  1217.  
  1218.                           GCOOPE USERS GROUP
  1219.  
  1220.                           RD2 BOX239AA
  1221.  
  1222.                           CLEARVILLE, PA.  15535
  1223.  
  1224.                     Please include my middle name to avoid local post office
  1225.                     difficulties :).
  1226.  
  1227.  
  1228.                      User's group members receive the latest updates to the
  1229.                 GCOOPE system, new class libraries, expansion modules, etc.
  1230.                 Limited free technical support over the phone is available,
  1231.                 and access is granted to a User's group only private limited
  1232.                 access bbs, you will be added to the quarterly newsletter
  1233.                 mailing list, and other services are available.
  1234.  
  1235.                      It is my hope that the user's group members will
  1236.                 participate in the growth of the GCOOPE system, expanding
  1237.                 its libraries and its capabilities.  This way, all user's of
  1238.                 the framework will benefit from a degree of co-operation
  1239.                 that is often impossible to achieve with a commercial
  1240.                 product.
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.                                           19
  1266.  
  1267.  
  1268.            Appendix B. Appendix B. About the Author (in case you're really
  1269.            bored)
  1270.  
  1271.                      The author is a starving artist type, currently
  1272.                 unemployed and living in the mountains of south central
  1273.                 Pennsylvania (Hi-technology's equivalent of Bumf---, Egypt).
  1274.                 First introduced to computers after a tour in the USAF as a
  1275.                 television studio technician in 1982.  First programming
  1276.                 experience in assembly language on Intertec (who?)
  1277.                 SuperBrain II CP/M and Atari 800XL machines.
  1278.  
  1279.                      Catching the PC wave, the author worked throughout most
  1280.                 of the 80s as a computer technician/consultant ending up
  1281.                 working in the computer evaluation laboratory of Entre'
  1282.                 computer corporate where he was allowed to play with early
  1283.                 networks, CAD/CAM, and the first 386 machines.  For the late
  1284.                 80's and early 90's the author was a self employed
  1285.                 electronic systems and circuit designer/consultant having
  1286.                 some success with early video frame digitizer designs for
  1287.                 the Apple Macintosh II before they butchered its expansion
  1288.                 slot capacity.
  1289.  
  1290.                      The last few years spent working with embedded systems
  1291.                 such as traffic control computers and monitors and playing
  1292.                 around with computer languages, the author began his
  1293.                 programming career in C in 1993.  GCOOPE is his first
  1294.                 publicly released software package.  When not working on the
  1295.                 GCOOPE project or his (t)rusty '70 Ford F-150, the author is
  1296.                 working with local business and political interests to
  1297.                 establish a free public access bbs and Internet link in his
  1298.                 home county.
  1299.  
  1300.                      Anyone need the above talents for a paid job???
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.                                           20
  1328. 
  1329.